home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
359_11
/
patch5.000
/
GO32_PAGING.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-11
|
17KB
|
692 lines
/* This is file PAGING.C */
/*
** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
/* History:112,12 */
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
#include "build.h"
#include "types.h"
#include "paging.h"
#include "graphics.h"
#include "tss.h"
#include "idt.h"
#include "gdt.h"
#include "valloc.h"
#include "dalloc.h"
#include "utils.h"
#include "aout.h"
#include "mono.h"
#include "vcpi.h"
#define VERBOSE 0
#if DEBUGGER
#define MAX_PAGING_NUM 1
#else
#define MAX_PAGING_NUM 4
#endif
extern word32 ptr2linear(void far *ptr);
CLIENT client; /* VCPI Change Mode Structure */
word32 abs_client; /* _DS * 16L + &client */
far32 vcpi_entry;
SYS_TBL int_descriptor;
SYS_TBL gbl_descriptor;
extern word16 vcpi_installed; /* VCPI Installed Flag */
extern near protect_entry();
extern TSS *utils_tss;
extern int debug_mode;
extern word16 mem_avail;
extern int self_contained;
extern long header_offset;
typedef struct AREAS {
word32 first_addr;
word32 last_addr;
word32 foffset; /* corresponding to first_addr; -1 = zero fill only */
} AREAS;
#define MAX_AREA 8
static AREAS areas[MAX_AREA];
static char *aname[MAX_AREA] = {
"text ",
"data ",
"bss ",
"arena",
"stack",
"vga ",
"syms ",
"emu"
};
static char achar[MAX_AREA] = "tdbmsg?e";
typedef enum {
A_text,
A_data,
A_bss,
A_arena,
A_stack,
A_vga,
A_syms,
A_emu
} AREA_TYPES;
static aout_f;
static emu_f;
word32 far *pd = 0;
word32 far *graphics_pt;
extern word32 graphics_pt_lin;
char paging_buffer[4096*MAX_PAGING_NUM];
/* VCPI Get Interface */
void link_vcpi(word32 far *dir, word32 far *table)
{
vcpi_entry.selector = g_vcpicode * 8;
vcpi_entry.offset32 = get_interface(table,&gdt[g_vcpicode]);
if (vcpi_entry.offset32 == -1L)
{
printf("CAUTION !!!! This EMS driver used address 1B0000H.\n");
printf("This memory area is broken by handle_screen_swap().\n");
exit(1);
}
int_descriptor.limit_16 = sizeof(idt);
int_descriptor.base_32 = ptr2linear(idt);
gbl_descriptor.limit_16 = sizeof(gdt);
gbl_descriptor.base_32 = ptr2linear(gdt);
client.page_table = (word32)dir>>12;
client.gdt_address = ptr2linear(&gbl_descriptor);
client.idt_address = ptr2linear(&int_descriptor);
client.ldt_selector = 0;
client.tss_selector = g_ctss * 8;
client.entry_eip = (word16)protect_entry;
client.entry_cs = g_rcode * 8;
abs_client = ptr2linear(&client);
}
handle_screen_swap(word32 far *pt)
{
struct REGPACK r;
int have_mono=0;
int have_color=0;
int have_graphics=0;
int save, new, i;
r.r_ax = 0x1200;
r.r_bx = 0xff10;
r.r_cx = 0xffff;
intr(0x10, &r);
if (r.r_cx == 0xffff)
pokeb(0x40, 0x84, 24); /* the only size for CGA/MDA */
save = peekb(screen_seg, 0);
pokeb(screen_seg, 0, ~save);
new = peekb(screen_seg, 0);
pokeb(screen_seg, 0, save);
if (new == ~save)
have_color = 1;
save = peekb(0xb000, 0);
pokeb(0xb000, 0, ~save);
new = peekb(0xb000, 0);
pokeb(0xb000, 0, save);
if (new == ~save)
have_mono = 1;
r.r_ax = 0x0f00;
intr(0x10, &r);
if ((r.r_ax & 0xff) > 0x07)
have_graphics = 1;
if (have_graphics && have_mono)
have_color = 1;
else if (have_graphics && have_color)
have_mono = 1;
for (i=0; i<16; i++)
pt[0x1b0+i] = pt[0xb0+i];
if (have_color && !have_mono)
{
for (i=0; i<8; i++)
pt[0x1b0+i] = pt[0xb8+i];
return;
}
if (have_mono & !have_color)
{
for (i=0; i<8; i++)
pt[0x1b8+i] = pt[0xb0+i];
return;
}
if ((biosequip() & 0x0030) == 0x0030) /* mono mode, swap! */
{
for (i=0; i<8; i++)
{
pt[0x1b0+i] ^= pt[0x1b8+i];
pt[0x1b8+i] ^= pt[0x1b0+i];
pt[0x1b0+i] ^= pt[0x1b8+i];
}
return;
}
}
paging_set_file(char *fname)
{
word32 far *pt;
FILEHDR filehdr;
AOUTHDR aouthdr;
SCNHDR scnhdr[3];
GNU_AOUT gnu_aout;
int i;
aout_f = open(fname, O_RDONLY|O_BINARY);
if (aout_f < 0)
{
printf("Can't open file <%s>\n", fname);
exit(1);
}
#if TOPLINEINFO
for (i=0; fname[i]; i++)
poke(screen_seg, i*2+10, fname[i] | 0x0700);
#endif
lseek(aout_f, header_offset, 0);
read(aout_f, &filehdr, sizeof(filehdr));
if (filehdr.f_magic != 0x14c)
{
lseek(aout_f, header_offset, 0);
read(aout_f, &gnu_aout, sizeof(gnu_aout));
a_tss.tss_eip = gnu_aout.entry;
aouthdr.tsize = gnu_aout.tsize;
aouthdr.dsize = gnu_aout.dsize;
aouthdr.bsize = gnu_aout.bsize;
}
else
{
read(aout_f, &aouthdr, sizeof(aouthdr));
a_tss.tss_eip = aouthdr.entry;
read(aout_f, scnhdr, sizeof(scnhdr));
}
a_tss.tss_cs = g_acode*8;
a_tss.tss_ds = g_adata*8;
a_tss.tss_es = g_adata*8;
a_tss.tss_fs = g_adata*8;
a_tss.tss_gs = g_adata*8;
a_tss.tss_ss = g_adata*8;
a_tss.tss_esp = 0x7ffffffc;
if (filehdr.f_magic == 0x14c)
{
areas[0].first_addr = aouthdr.text_start + ARENA;
areas[0].foffset = scnhdr[0].s_scnptr + header_offset;
areas[0].last_addr = areas[0].first_addr + aouthdr.tsize;
}
else if (filehdr.f_magic == 0x10b)
{
areas[0].first_addr = ARENA;
if (a_tss.tss_eip >= 0x1000) /* leave space for null reference */
areas[0].first_addr += 0x1000; /* to cause seg fault */
areas[0].foffset = header_offset;
areas[0].last_addr = areas[0].first_addr + aouthdr.tsize + 0x20;
}
#if DEBUGGER
else if (filehdr.f_magic == 0x107)
{
struct stat sbuf;
fstat(aout_f, &sbuf);
areas[0].first_addr = ARENA;
areas[0].foffset = 0x20 + header_offset;
areas[0].last_addr = sbuf.st_size + ARENA - 0x20;
}
else
{
struct stat sbuf;
fstat(aout_f, &sbuf);
areas[0].first_addr = ARENA;
areas[0].foffset = header_offset;
areas[0].last_addr = sbuf.st_size + ARENA;
}
#else
else
{
printf("Unknown file type 0x%x (0%o)\n", filehdr.f_magic, filehdr.f_magic);
exit(-1);
}
#endif
#if DEBUGGER
if (debug_mode)
printf("%ld+", aouthdr.tsize);
#endif
if (filehdr.f_magic == 0x14c)
{
areas[1].first_addr = aouthdr.data_start + ARENA;
areas[1].foffset = scnhdr[1].s_scnptr + header_offset;
}
else
{
areas[1].first_addr = (areas[0].last_addr+0x3fffffL)&~0x3fffffL;
areas[1].foffset = ((aouthdr.tsize + 0x20 + 0xfffL) & ~0xfffL) + header_offset;
}
areas[1].last_addr = areas[1].first_addr + aouthdr.dsize - 1;
#if DEBUGGER
if (debug_mode)
printf("%ld+", aouthdr.dsize);
#endif
areas[2].first_addr = areas[1].last_addr + 1;
areas[2].foffset = -1;
areas[2].last_addr = areas[2].first_addr + aouthdr.bsize - 1;
#if DEBUGGER
if (debug_mode)
printf("%ld = %ld\n", aouthdr.bsize,
aouthdr.tsize+aouthdr.dsize+aouthdr.bsize);
#endif
areas[3].first_addr = areas[2].last_addr;
areas[3].last_addr = areas[3].first_addr;
areas[3].foffset = -1;
areas[4].first_addr = 0x50000000;
areas[4].last_addr = 0x8fffffff;
areas[4].foffset = -1;
areas[5].first_addr = 0xe0000000;
areas[5].last_addr = 0xe03fffff;
areas[5].foffset = -1;
areas[A_syms].first_addr = 0xa0000000;
areas[A_syms].last_addr = 0xafffffff;
areas[A_syms].foffset = -1;
pd = (word32 far *)((long)valloc(VA_640) << 24);
pt = (word32 far *)((long)valloc(VA_640) << 24);
for (i=0; i<1024; i++)
pd[i] = 0;
if (vcpi_installed)
{
link_vcpi(pd,pt); /* Ge